home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PRINTER
/
JPSRC11.ARJ
/
JETL2D.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-04
|
28KB
|
845 lines
/*
* JET PAK - HP DeskJet and LaserJet series printer utilities
*
* JETL2D program - convert from LaserJet to DeskJet soft font file
*
* Version 1.1 (Public Domain)
*/
/* system include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* application include files */
#include "patchlev.h"
#include "jetfont.h"
#include "jetutil.h"
#include "jetbmp.h"
/*
* MODULE GLOBAL DATA
*/
/* baseline distance for bottom pass */
static UNSIGNEDINT baseline;
/* pitch is needed for converting landscape characters */
static UNSIGNEDINT pitch;
/* portrait or landscape font */
static UNSIGNEDBYTE orientation;
/* fixed or proportional spacing font */
static UNSIGNEDINT spacing;
/* DJ, DJ+ or DJ500 output character format */
static UNSIGNEDBYTE charformat;
/* input and output font commands being processed */
static FONT_COMMAND infc, outfc;
/* output file suffix */
static char output_suffix[SUFFIX_MAX] = ".l2d";
/* DJ500 support required? */
static BOOLEAN dj500_support = TRUE;
/* bitmap optimisation required? */
static BOOLEAN bitmap_optimisation = TRUE;
/* bitmap optimisation null smoothing data */
static UNSIGNEDBYTE *smooth_null = NULL;
/* record the worst side bearing loss to left and right */
static SIGNEDINT worst_left_loss, worst_right_loss;
static UNSIGNEDINT worst_left_char, worst_right_char;
/* compact bitmap structure */
typedef struct compact_ljchar_struct {
SIGNEDINT left_offset;
SIGNEDINT top_offset;
UNSIGNEDINT character_width;
UNSIGNEDINT character_height;
SIGNEDINT delta_x;
UNSIGNEDBYTE *bitmap;
UNSIGNEDBYTE *smooth;
} COMPACT_LJCHAR;
static COMPACT_LJCHAR ljchars[256] = { 0 };
#define sizeofljbitmap(w,h) (((w + 7)/8)*h)
/*
* LOCAL FUNCTIONS
*/
static void usage_wrong()
{
/*
* Print usage message and exit.
*/
fprintf(stderr, USAGE_HEADER);
fprintf(stderr, "Usage: JETL2D [-h] [-j] [-o] [-t filetype] ljfontfile [ljfontfile...]\n\n");
fprintf(stderr, "Convert LaserJet font files to DeskJet format\n\n");
fprintf(stderr, " -h print this usage information\n");
fprintf(stderr, " -j disable bitmap smoothing\n");
fprintf(stderr, " -o disable DJ500 support\n");
fprintf(stderr, " -t filetype change output file type (default %s)\n", output_suffix);
fprintf(stderr, " ljfontfile name of LaserJet format soft font file to be converted\n");
exit(1);
}
static int ljchar_create(charcode, infcp)
UNSIGNEDINT charcode;
FONT_COMMAND *infcp;
{
/*
* Save the information in a LaserJet character descriptor to
* a compact LaserJet character structure
*/
struct ljchar_struct *ljp;
/* issue a warning if the character descriptor is in a strange format */
if (infcp->data.character.format != LJCHARFORMAT)
fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
os_dir, os_file, infcp->data.character.format);
/* check for a character width or height bigger than can be supported
on the DJ */
if ( (infcp->data.character.data.ljchar.character_width*2 > MAX_CELL_WIDTH)
|| (infcp->data.character.data.ljchar.character_height > MAX_CELL_HEIGHT) )
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
/* check this isn't a continuation */
if (infcp->data.character.continuation != 0)
{
fprintf(stderr, ERROR_CONTINUATION, os_dir, os_file);
return(ERROR);
}
/* check the character code is in range */
if (charcode >= sizeofarray(ljchars))
{
fprintf(stderr, ERROR_CODE_TOO_BIG, os_dir, os_file, charcode);
return(ERROR);
}
/* OK to save the information */
ljp = &infcp->data.character.data.ljchar;
ljchars[charcode].left_offset = ljp->left_offset;
ljchars[charcode].top_offset = ljp->top_offset;
ljchars[charcode].character_width = ljp->character_width;
ljchars[charcode].character_height = ljp->character_height;
/* for fixed fonts, derive the character escapement from the
pitch: the delta X value is sometimes invalid */
if (spacing == FIXED)
ljchars[charcode].delta_x = pitch*4;
else
ljchars[charcode].delta_x = ljp->delta_x;
if ((ljchars[charcode].bitmap =
zalloc(sizeofljbitmap(ljp->character_width, ljp->character_height))) == NULL)
{
fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
return(ERROR);
}
memcpy(ljchars[charcode].bitmap, ljp->bitmap,
sizeofljbitmap(ljp->character_width, ljp->character_height));
if (bitmap_optimisation)
{
if ((ljchars[charcode].smooth =
zalloc(sizeofljbitmap(ljp->character_width, ljp->character_height))) == NULL)
{
fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
return(ERROR);
}
if (bitmap_smooth(ljchars[charcode].bitmap, ljchars[charcode].smooth, ljp->character_width, ljp->character_height) == ERROR)
{
fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
return(ERROR);
}
}
else
{
if (smooth_null == NULL)
{
/* allocate and zeroise null smoothing data */
if ((smooth_null = zalloc(BITMAP_SIZE_MAX)) == NULL)
{
fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
return(ERROR);
}
}
/* point smoothing data for all bitmaps at same data */
ljchars[charcode].smooth = smooth_null;
}
return(OK);
}
static void ljchar_free_all()
{
/*
* Free the resources used in all the compact LaserJet characters.
*/
UNSIGNEDINT charcode;
for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
{
if (ljchars[charcode].bitmap != NULL)
{
free(ljchars[charcode].bitmap);
ljchars[charcode].bitmap = NULL;
}
if (bitmap_optimisation)
{
if (ljchars[charcode].smooth != NULL)
{
free(ljchars[charcode].smooth);
ljchars[charcode].smooth = NULL;
}
}
else
{
if (smooth_null != NULL)
{
free(smooth_null);
smooth_null = NULL;
}
ljchars[charcode].smooth = NULL;
}
}
}
static int fdc_lj_to_dj(infcp, outfcp)
FONT_COMMAND *infcp, *outfcp;
{
/*
* Convert a LaserJet font descriptor command to a DeskJet font
* descriptor command.
*
* In the output Deskjet fonts, the nominal design cell expands to
* fill an integral number of printer head passes, with the bitmap
* data shifting down, so the bottom of the LJ design cell aligns
* with the bottom of the DJ design cell.
*
* The resulting baseline position relative to the origin of the
* bottom DJ pass is saved in 'baseline'. Baselines for the other
* passes can be derived from this by adding MULTI_PASS_OFFSET
* for each pass.
*
* 'charformat', 'pitch' and orientation save additional header
* information required during character descriptor processing.
*
* The number of passes required in the DJ font is returned.
*/
int passes;
FONT_DESCRIPTOR *fdp;
int i;
/* check input file is in correct format */
if ( (infcp->data.font.header_format == DJFONTFORMAT)
|| (infcp->data.font.header_format == DJPFONTFORMAT)
|| (infcp->data.font.header_format == DJ500FONTFORMAT) )
{
fprintf(stderr, ERROR_DESKJET, os_dir, os_file);
return(ERROR);
}
else if (infcp->data.font.header_format != LJFONTFORMAT)
{
fprintf(stderr, WARNING_BAD_FONT_FORMAT,
os_dir, os_file, infcp->data.font.header_format);
}
outfcp->command_type = infcp->command_type;
if (dj500_support)
outfcp->number = DJ500FDSIZE+DJ500SSIZE;
else
outfcp->number = DJFDSIZE+DJSSIZE;
/* most of the font descriptor fields can be copied straight
across; a lot of LaserJet fonts have junk in many of the
fields, so this will be garbage-in-garbage-out; however, that
seems to be OK since most of the affected fields aren't used
by the DJ either */
outfcp->data.font = infcp->data.font;
/* now change the standard font descriptor bits that are different */
fdp = &outfcp->data.font;
if (dj500_support)
fdp->size = DJ500FDSIZE;
else
fdp->size = DJFDSIZE;
/* quality is best set to Letter Quality, so that algorithmic
draft is used for the font if the printer is set to NLQ or
Draft mode. Most LJ fonts will have 0 for this field: if this
is just copied over, the font would always be printed "as is"
regardless of what quality the user selected */
fdp->quality = 2;
/* placement must be normal (ie not super- or sub- script) */
fdp->placement = 0;
/* last code is used on the DJ and should have a reasonable upper limit value */
if (fdp->type == FONT_TYPE_7BIT)
fdp->last_code = 127;
else
fdp->last_code = 255;
/* add the extended font descriptor bits ... */
fdp->h_pixel_resolution = 600;
fdp->v_pixel_resolution = 300;
/* initialise multi-pass baseline offsets - may be overridden */
fdp->baseline_offset_2 = 0;
fdp->baseline_offset_3 = 0;
fdp->baseline_offset_4 = 0;
/* convert the bitmap related data - depends on orientation */
if (fdp->orientation == LANDSCAPE)
{
fdp->cell_height *= 2; /* -> 600 dpi in X direction */
/* only fixed width fonts are supported in landscape mode */
if (fdp->spacing != FIXED)
{
fprintf(stderr, ERROR_LANDSCAPE_FIXED, os_dir, os_file);
return(ERROR);
}
/* fixed character width must be printable in one head pass */
if (fdp->pitch > PASS_HEIGHT*4)
{
fprintf(stderr, ERROR_FONT_TOO_BIG, os_dir, os_file);
return(ERROR);
}
/* one pass required */
passes = 1;
/* EMPIRICAL HACK FOLLOWS: this is done to ensure the soft
font character's baseline align correctly with other
landscape fonts. The baseline offsets themselves don't
seem to be important but the difference is: the difference
must be equal to the baseline distance in 300 dpi units.
I can only guess at why this should be, since it isn't
explained in the manual, and I've not seen any real
landscape soft fonts for the DJ+ for comparision. */
fdp->baseline_offset_2 = fdp->baseline_distance*2;
}
else /* PORTRAIT */
{
fdp->cell_width *= 2; /* -> 600 dpi in X direction */
/* now deal with splitting the design cell up into multiple passes */
passes = 1 + (fdp->cell_height - 1 - PASS_OVERLAP)/MULTI_PASS_OFFSET;
/* check for design cells bigger than can be supported on the DJ */
if (passes > 4)
{
fprintf(stderr, ERROR_FONT_TOO_BIG, os_dir, os_file);
return(ERROR);
}
/* shift the LJ baseline so the bottom of the DJ cell aligns
with the bottom of the bottom pass */
fdp->baseline_distance += (MULTI_PASS_OFFSET*passes + PASS_OVERLAP)
- fdp->cell_height;
fdp->cell_height = passes * PASS_HEIGHT;
/* now fix up the baselines for all the passes */
switch (passes)
{
/* !! intended drop-throughs !! */
case 4:
fdp->baseline_offset_4 = fdp->baseline_distance;
fdp->baseline_distance -= MULTI_PASS_OFFSET;
case 3:
fdp->baseline_offset_3 = fdp->baseline_distance;
fdp->baseline_distance -= MULTI_PASS_OFFSET;
case 2:
fdp->baseline_offset_2 = fdp->baseline_distance;
fdp->baseline_distance -= MULTI_PASS_OFFSET;
}
}
/* fix up out-of-range underline parameters */
if ( (((SIGNEDBYTE)fdp->baseline_distance - fdp->underline_distance) <= UNDERLINE_MIN)
|| (((SIGNEDBYTE)fdp->baseline_distance - fdp->underline_distance + (SIGNEDBYTE)fdp->underline_height) > UNDERLINE_MAX) )
{
fdp->underline_height = underline_height_for_height(fdp->height);
fdp->underline_distance = (SIGNEDBYTE)fdp->baseline_distance
+ (SIGNEDBYTE)fdp->underline_height
- (SIGNEDBYTE)UNDERLINE_MAX;
}
/* add the printer specific font bits ... */
if (dj500_support)
fdp->specific_size = DJ500SSIZE;
else
fdp->specific_size = DJSSIZE;
/* ... this may be used by soft font downloaders, but not by the
printer - it's too much hassle to fix up right now */
fdp->data_size = 0;
/* ... half pitch mustn't be allowed for proportional fonts */
if (fdp->spacing == FIXED)
fdp->no_half_pitch = 0;
else
fdp->no_half_pitch = 1;
/* ... 0 is a safe default for all these fields */
fdp->compressed = 0;
fdp->no_double_pitch = 0;
fdp->no_half_height = 0;
fdp->no_bold = 0;
fdp->no_draft = 0;
fdp->bold_method = 0;
fdp->reserved3 = 0;
/* ... hold time factor should be set to 0 */
fdp->hold_time_factor = 0;
/* ... include double underline parameters based on the single
underline parameters in the standard font descriptor */
fdp->bdu_height = (fdp->underline_height + 1)/2;
fdp->tdu_height = fdp->bdu_height;
fdp->bdu_distance = fdp->underline_distance
- (SIGNEDBYTE)fdp->underline_height
+ (SIGNEDBYTE)fdp->bdu_height;
fdp->tdu_distance = fdp->bdu_distance
+ ((SIGNEDBYTE)fdp->bdu_height)*2;
/* fill name extension with blanks */
for (i = 0; i < sizeof(fdp->name_extension); i++)
fdp->name_extension[i] = ' ';
/* add identifying suffix to existing copyright notice */
if ((strlen(fdp->comment) + sizeof(JETL2D_COMMENT_SUFFIX)) < COMMENT_SIZE_MAX)
strcat(fdp->comment, JETL2D_COMMENT_SUFFIX);
outfcp->number += strlen(fdp->comment);
/* save parameters needed in character descriptor processing */
baseline = fdp->baseline_distance;
pitch = fdp->pitch/4;
orientation = fdp->orientation;
spacing = fdp->spacing;
/* play safe and force all multi-pass fonts to be unidirectional
to encourage better registration between the passes. Is there
a better way of working out what should go in this field? */
if (passes > 1)
fdp->unidirection = 1;
else
fdp->unidirection = 0;
/* save the font and character format magic numbers */
if (dj500_support)
{
/* font only usable on DJ500 */
fprintf(stderr, WARNING_DJ500_ONLY, os_dir, os_file);
fdp->header_format = DJ500FONTFORMAT;
charformat = DJ500CHARFORMAT;
}
else if (orientation == LANDSCAPE)
{
/* landscape font - DeskJet+ printer only */
fprintf(stderr, WARNING_DJ_LANDSCAPE, os_dir, os_file);
fdp->header_format = DJPFONTFORMAT;
charformat = DJPCHARFORMAT;
}
else if (passes > 2)
{
/* > 98 dot cell height - DeskJet+ printer only */
fprintf(stderr, WARNING_DJ_TOO_LARGE, os_dir, os_file);
fdp->header_format = DJPFONTFORMAT;
charformat = DJPCHARFORMAT;
}
else
{
/* <= 98 dot cell height - any DeskJet series printer */
fdp->header_format = DJFONTFORMAT;
charformat = DJCHARFORMAT;
}
return(passes);
}
static int cdc_lj_to_dj(charcode, inccp, outfcp, char_type)
UNSIGNEDINT charcode;
COMPACT_LJCHAR *inccp;
FONT_COMMAND *outfcp;
int char_type; /* single pass or pass number in multi-pass */
{
/*
* Copy a compact LaserJet character and bitmap to
* a Deskjet character descriptor and bitmap command.
*/
UNSIGNEDBYTE *data, *sdata;
int blanklines, datalines, pass, r;
struct djchar_struct *djp;
UNSIGNEDINT left_pad = 0, right_pad = 0;
SIGNEDINT left_offset, right_offset;
outfcp->command_type = CDC;
/* deal with the preamble bits */
outfcp->data.character.format = charformat;
outfcp->data.character.continuation = 0;
/* deal with the character descriptor proper */
djp = &outfcp->data.character.data.djchar;
djp->descriptor_size = DJCDSIZE;
djp->char_type = char_type;
djp->character_width = inccp->character_width*2; /* -> 600 dpi */
/* positioning in X (raster scan) direction - depends on orientation */
if (orientation == LANDSCAPE)
{
/* the compressed width is reused as the left pad in landscape
fonts */
djp->comp_width = 2*(baseline+inccp->left_offset);
djp->left_offset = 0;
djp->right_offset = 0;
}
else /* PORTRAIT */
{
djp->comp_width = 0; /* no algorithmic compression */
/* get the DJ left and right offsets in 600 dpi units */
left_offset = inccp->left_offset*2;
right_offset = inccp->delta_x/2 - left_offset - djp->character_width;
if (spacing == FIXED)
{
/* left and right offset fields are ignored, horizontal
alignment must be done by padding the bitmap */
if (left_offset < right_offset)
right_pad = (UNSIGNEDINT)(right_offset - left_offset);
else
left_pad = (UNSIGNEDINT)(left_offset - right_offset);
/* character width must be increased to take into account
the pad columns */
djp->character_width += (UNSIGNEDBYTE)(left_pad + right_pad);
left_offset = 0;
right_offset = 0;
}
if (dj500_support)
{
djp->left_offset = (SIGNEDBYTE)left_offset;
djp->right_offset = (SIGNEDBYTE)right_offset;
}
else
{
/* throw away any -ve side bearing - keep track of the worst
loss in 300 dpi units */
if (left_offset < 0)
{
if (left_offset/2 < worst_left_loss)
{
worst_left_loss = left_offset/2;
worst_left_char = charcode;
}
djp->left_offset = 0;
}
else
{
djp->left_offset = (SIGNEDBYTE)left_offset;
}
/* throw away any -ve side bearing - keep track of the worst
loss in 300 dpi units */
if (right_offset < 0)
{
if (right_offset/2 < worst_right_loss)
{
worst_right_loss = right_offset/2;
worst_right_char = charcode;
}
djp->right_offset = 0;
}
else
{
djp->right_offset = (SIGNEDBYTE)right_offset;
}
}
}
/* positioning in Y (paper motion) direction - depends on orientation */
if (orientation == LANDSCAPE)
{
blanklines = pitch - inccp->top_offset;
data = inccp->bitmap;
sdata = inccp->smooth;
datalines = inccp->character_height;
if (blanklines < 0)
{
data += ((inccp->character_width + 7)/8) * (-blanklines);
sdata += ((inccp->character_width + 7)/8) * (-blanklines);
datalines += blanklines;
blanklines = 0;
}
if (datalines > (pitch - blanklines))
datalines = pitch - blanklines;
if (datalines < 0)
datalines = 0;
}
else /* PORTRAIT */
{
/* work out the number of blank lines preceding the pass data */
pass = pass_for_char_type(char_type);
blanklines = (int)baseline
+ (int)pass*MULTI_PASS_OFFSET
- (int)inccp->top_offset;
data = inccp->bitmap;
sdata = inccp->smooth;
if (blanklines < 0)
{
data += ((inccp->character_width + 7)/8) * (-blanklines);
sdata += ((inccp->character_width + 7)/8) * (-blanklines);
blanklines = 0;
}
else if (blanklines > lines_for_pass(pass))
{
blanklines = lines_for_pass(pass);
}
/* work out the number of lines of bitmap data in the pass */
datalines = (int)inccp->character_height
+ (int)baseline
+ (int)pass*MULTI_PASS_OFFSET
- (int)inccp->top_offset;
if (datalines > (int)inccp->character_height)
datalines = (int)inccp->character_height;
if (datalines > (lines_for_pass(pass) - blanklines))
datalines = lines_for_pass(pass) - blanklines;
if (datalines < 0)
datalines = 0;
}
/* now convert the bitmap itself */
if ((r = bitmap_lj_to_dj(data, sdata, inccp->character_width, datalines,
blanklines, left_pad, right_pad, djp->bitmap,
sizeof(djp->bitmap))) == ERROR)
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
/* calculate the total number of bytes in descriptor */
outfcp->number = 2 + DJCDSIZE + r;
return(OK);
}
static void jetl2d()
{
char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN], *sp;
FILE *infp, *outfp;
int r, pass, npasses = 0;
char worst_char_string[10];
UNSIGNEDINT charcode;
/* build the input and output file paths */
strcpy(inpath, os_dir);
strcat(inpath, os_file);
strcpy(outpath, os_file);
if ((sp = strrchr(outpath, '.')) == NULL)
strcat(outpath, output_suffix);
else
strcpy(sp, output_suffix);
/* rudimentary check for input overwriting output */
if (strcmp(inpath, outpath) == 0)
{
fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
return;
}
if (!(infp = fopen(inpath, "rb")))
{
fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
return;
}
if (!(outfp = fopen(outpath, "wb")))
{
fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
fclose(infp);
return;
}
/* initialise per input file data */
worst_left_loss = 0;
worst_right_loss = 0;
/* copy the font header and load the characters into memory */
while ((r = font_command_read(infp, &infc)) == OK)
{
switch(infc.command_type)
{
case FDC:
if ((npasses = fdc_lj_to_dj(&infc, &outfc)) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
break;
case CCC:
charcode = infc.number;
break;
case CDC:
if (ljchar_create(charcode, &infc) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
break;
}
}
/* copy the pass(es) of a multi-pass font */
for (pass = 0; pass < npasses && r == EOF; pass++)
{
for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
{
if (ljchars[charcode].bitmap != NULL)
{
/* output the character code command */
outfc.command_type = CCC;
outfc.number = charcode;
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
/* convert the character descriptor and bitmap */
if (cdc_lj_to_dj(charcode, &ljchars[charcode], &outfc,
npasses == 1?CHAR_TYPE_NORMAL:char_type_for_pass(pass)) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
/* output the character descriptor and bitmap */
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
}
}
}
if (npasses == 0 || r != EOF)
/* error scenarios: (npasses == 0) means no font descriptor found,
probably processing a text file; (r != EOF) means a font
command escape sequence wasn't read in correctly, probably
processing a binary file or a truncated soft font file */
fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
else
{
/* give warnings about negative side bearing lost if any */
if (worst_left_loss < 0)
{
if (isascii(worst_left_char) && isprint(worst_left_char))
sprintf(worst_char_string, "%c", worst_left_char);
else
sprintf(worst_char_string, "\\%03o", worst_left_char);
fprintf(stderr, WARNING_SIDE_BEARING, os_dir, os_file,
"left", worst_left_loss, worst_char_string);
}
if (worst_right_loss < 0)
{
if (isascii(worst_right_char) && isprint(worst_right_char))
sprintf(worst_char_string, "%c", worst_right_char);
else
sprintf(worst_char_string, "\\%03o", worst_right_char);
fprintf(stderr, WARNING_SIDE_BEARING, os_dir, os_file,
"right", worst_right_loss, worst_char_string);
}
fprintf(stderr, OK_JETL2D, os_dir, os_file, outpath);
}
ljchar_free_all();
fclose(infp);
fclose(outfp);
}
main(argc, argv)
int argc;
char *argv[];
{
char c;
/* stop getopt() printing errors */
opterr = FALSE;
while ((c = getopt(argc, argv, "t:hjo")) != EOF)
{
switch (c)
{
case 't':
strncpy(output_suffix+1, optarg, SUFFIX_MAX-2);
output_suffix[SUFFIX_MAX-1] = '\0';
break;
case 'o':
dj500_support = FALSE;
break;
case 'j':
bitmap_optimisation = FALSE;
break;
case 'h':
case '?':
/* help required, or invalid option specified */
usage_wrong();
}
}
/* must specify at least one file */
if (optind >= argc)
usage_wrong();
/* process file arguments */
if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
fprintf(stderr, ERROR_OUT_OF_HEAP);
while (os_getfile() != EOF)
jetl2d();
return(0);
}